package de.jmda.mproc.swingui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.FocusEvent;
import java.beans.PropertyChangeEvent;
import java.io.File;

import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;

import de.jmda.gui.swing.mvc.AbstractController;
import de.jmda.util.fileset.FileFilterDirectoriesAndJavaSourceFilesOnly;
import de.jmda.util.fileset.FileFilterDirectoriesOnly;
import de.jmda.util.fileset.FileSet.RuleSetUpdateMode;
import de.jmda.util.fileset.FileSetJavaFilesOnly;
import de.jmda.util.gui.swing.JPanelFavourites;
import de.jmda.util.gui.swing.JPanelFavouritesModel;

/**                                                                                    
 * This class was initially generated by {@link
 * de.jmda.gui.swing.mvc.ControllerSupportEnabledGenerator}.    
 * <p>                                                                                 
 * <code>ControllerSupportEnabledGenerator</code> will not regenerate this
 * class, hence modifications will not get lost due to subsequent generation by
 * <code>ControllerSupportEnabledGenerator</code>.                                         
 */                                                                                    
class JPanelFileSetJavaSourceFilesController
		extends AbstractController<JPanelFileSetJavaSourceFilesModel>       
{                                                                                      
	private JPanelFileSetJavaSourceFilesControllerContext context;
	
	private JPanelFileSetJavaSourceFilesModel model;
	
	private FileSetJavaFilesOnly fileSetJavaFilesOnly;
	
	private JPanelFavouritesModel jPanelFavouritesModel;
	
	private JList mostRecentlySelectedJList;
	
	private File mostRecentlyVisitedDirectory = new File(".");

	/**                                                                                  
	 * Constructor                                                                       
	 */                                                                                  
	JPanelFileSetJavaSourceFilesController(                                                             
			de.jmda.gui.swing.mvc.ControllerContextProvider controllerContextProvider)     
	{                                                                                    
		super(controllerContextProvider);                                                  
		refreshControllerContext();
	}

	@Override
  public void refreshControllerContext()
  {
	  context =
	  		(JPanelFileSetJavaSourceFilesControllerContext)
	  				controllerContextProvider.getControllerContext();
  }
	
  /**
   * @see de.jmda.gui.swing.mvc.AbstractController#setModel(de.jmda.gui.swing.mvc.ModelBase)
   */
  @Override
	public void setModel(JPanelFileSetJavaSourceFilesModel model)
	{
		this.model = model;
		
		fileSetJavaFilesOnly = this.model.getFileSetJavaFilesOnly();
		jPanelFavouritesModel = this.model.getjPanelFavouritesModel();

		context.getJListSourcesRootDirectoriesIncludes().setModel(
				new ListModelSourcesRootDirectoriesIncludes(fileSetJavaFilesOnly));
		context.getJListSourcesRootDirectoriesExcludes().setModel(
				new ListModelSourcesRootDirectoriesExcludes(fileSetJavaFilesOnly));
		context.getJListSourcesDirectoriesIncludes().setModel(
				new ListModelSourcesDirectoriesIncludes(fileSetJavaFilesOnly));
		context.getJListSourcesDirectoriesExcludes().setModel(
				new ListModelSourcesDirectoriesExcludes(fileSetJavaFilesOnly));
		context.getJListSourcesFilesIncludes().setModel(
				new ListModelSourcesFilesIncludes(fileSetJavaFilesOnly));
		context.getJListSourcesFilesExcludes().setModel(
				new ListModelSourcesFilesExcludes(fileSetJavaFilesOnly));
		
		// disable buttons until a list gains the focus
		context.getJButtonAdd().setEnabled(false);
		context.getJButtonRemove().setEnabled(false);
		
		// TODO this does not seem to work
		// set focus to list
		context.getJListSourcesDirectoriesIncludes().requestFocusInWindow();
	}
	
	void rearrangeVerticalDividers()
	{
		int position = ((context.getJSplitPaneOuter().getSize().width - 15) / 3);
		context.getJSplitPaneOuter().setDividerLocation(position);
		context.getJSplitPaneInner().setDividerLocation(position);
	}
	
	void jSplitPaneLeftMiddleRightPropertyChange(PropertyChangeEvent evt)
	{
		if (context.getJCheckBoxSynchronizeHorizontalDividers().isSelected())
		{
			if (evt.getPropertyName().equals(JSplitPane.DIVIDER_LOCATION_PROPERTY))
			{
				Integer newDividerLocation = (Integer) evt.getNewValue();

				context.getJSplitPaneLeft().setDividerLocation(newDividerLocation);
				context.getJSplitPaneMiddle().setDividerLocation(newDividerLocation);
				context.getJSplitPaneRight().setDividerLocation(newDividerLocation);
			}
		}
	}

	void jListSourcesFocusGained(FocusEvent evt)
	{
		if (mostRecentlySelectedJList != null)
		{
			mostRecentlySelectedJList.clearSelection();

			// make possibly bordered scroll pane unbordered
			JScrollPane jScrollPane = getJScrollPane(mostRecentlySelectedJList);
			jScrollPane.setBorder(null);
		}
		
		mostRecentlySelectedJList = getJList(evt);
		
		// enable add button
		context.getJButtonAdd().setEnabled(true);

		if (mostRecentlySelectedJList.getSelectedIndex() < 0)
		{
			// indicate selected empty list with a bordered scroll pane
			JScrollPane jScrollPane = getJScrollPane(mostRecentlySelectedJList);
			jScrollPane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		}
		else
		{
			// if there is an element selected enable remove button
			context.getJButtonRemove().setEnabled(true);
		}
	}

	void jButtonAddActionPerformed(ActionEvent evt)
  {
		ChangeDirectoryListeningFileChooser changeDirectoryListeningFileChooser =
				new ChangeDirectoryListeningFileChooser(mostRecentlyVisitedDirectory);

		if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesIncludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select root directory to include");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesOnly()));
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesExcludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select root directory to exclude");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesOnly()));
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesIncludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select directory to include");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesOnly()));
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesExcludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select directory to exclude");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesOnly()));
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesIncludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select file to include");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesAndJavaSourceFilesOnly()));
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesExcludes())
		{
			changeDirectoryListeningFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
			changeDirectoryListeningFileChooser.setDialogTitle("select file to exclude");
			changeDirectoryListeningFileChooser.addChoosableFileFilter(new FileFilterWrapper(new FileFilterDirectoriesAndJavaSourceFilesOnly()));
		}
		
		JPanelFavourites jPanelFavourites =
				new JPanelFavourites(
						jPanelFavouritesModel,
						changeDirectoryListeningFileChooser.getCurrentDirectory());
		
		// let changeDirectoryListeningFileChooser react on change directory events
		// occuring in jPanelFavourites
		jPanelFavourites.addChangeDirectoryListener(
				changeDirectoryListeningFileChooser);
		
		// let jPanelFavourites react on property changes in
		// changeDirectoryListeningFileChooser
		changeDirectoryListeningFileChooser.addPropertyChangeListener(
				jPanelFavourites);
		
		changeDirectoryListeningFileChooser.setAccessory(jPanelFavourites);
		
		int jFileChooserResult =
				changeDirectoryListeningFileChooser.showDialog(
						context.getJPanelFileSetJavaSourceFiles(), "select");
		
		if (jFileChooserResult == JFileChooser.CANCEL_OPTION)
		{
			return;
		}
		
		File fileToAdd = changeDirectoryListeningFileChooser.getSelectedFile();

		if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesIncludes())
		{
			fileSetJavaFilesOnly.includeDirectoryRecursive(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesExcludes())
		{
			fileSetJavaFilesOnly.excludeDirectoryRecursive(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesIncludes())
		{
			fileSetJavaFilesOnly.includeDirectory(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesExcludes())
		{
			fileSetJavaFilesOnly.excludeDirectory(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesIncludes())
		{
			fileSetJavaFilesOnly.includeFile(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesExcludes())
		{
			fileSetJavaFilesOnly.excludeFile(fileToAdd, RuleSetUpdateMode.ADD_RULE);
		}
		
		setModel(model);
  }

	public void jButtonRemoveActionPerformed(ActionEvent evt)
  {
		File fileToRemove =
				new File((String) mostRecentlySelectedJList.getSelectedValue());

		if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesIncludes())
		{
			fileSetJavaFilesOnly.includeDirectoryRecursive(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesRootDirectoriesExcludes())
		{
			fileSetJavaFilesOnly.excludeDirectoryRecursive(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesIncludes())
		{
			fileSetJavaFilesOnly.includeDirectory(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesDirectoriesExcludes())
		{
			fileSetJavaFilesOnly.excludeDirectory(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesIncludes())
		{
			fileSetJavaFilesOnly.includeFile(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		else if (mostRecentlySelectedJList == context.getJListSourcesFilesExcludes())
		{
			fileSetJavaFilesOnly.excludeFile(fileToRemove, RuleSetUpdateMode.REMOVE_RULE);
		}
		
		setModel(model);
  }

	private JScrollPane getJScrollPane(Component component)
	{
		if (component == context.getJListSourcesRootDirectoriesIncludes())
		{
			return context.getJScrollPaneRootDirectoriesIncludes();
		}
		if (component == context.getJListSourcesRootDirectoriesExcludes())
		{
			return context.getJScrollPaneRootDirectoriesExcludes();
		}
		if (component == context.getJListSourcesDirectoriesIncludes())
		{
			return context.getJScrollPaneDirectoriesIncludes();
		}
		if (component == context.getJListSourcesDirectoriesExcludes())
		{
			return context.getJScrollPaneDirectoriesExcludes();
		}
		if (component == context.getJListSourcesFilesIncludes())
		{
			return context.getJScrollPaneFilesIncludes();
		}
		if (component == context.getJListSourcesFilesExcludes())
		{
			return context.getJScrollPaneFilesExcludes();
		}

		return null;		
	}
	
	private JList getJList(FocusEvent evt)
	{
		return getJList(evt.getComponent());
	}
	
	private JList getJList(Component component)
	{
		if (component == context.getJListSourcesRootDirectoriesIncludes())
		{
			return context.getJListSourcesRootDirectoriesIncludes();
		}
		if (component == context.getJListSourcesRootDirectoriesExcludes())
		{
			return context.getJListSourcesRootDirectoriesExcludes();
		}
		if (component == context.getJListSourcesDirectoriesIncludes())
		{
			return context.getJListSourcesDirectoriesIncludes();
		}
		if (component == context.getJListSourcesDirectoriesExcludes())
		{
			return context.getJListSourcesDirectoriesExcludes();
		}
		if (component == context.getJListSourcesFilesIncludes())
		{
			return context.getJListSourcesFilesIncludes();
		}
		if (component == context.getJListSourcesFilesExcludes())
		{
			return context.getJListSourcesFilesExcludes();
		}
		
		return null;
	}

	public void jButtonShowFilesActionPerformed(ActionEvent evt)
  {
		JScrollPane jScrollPane = new JScrollPane();

		JList jList =
				new JList(fileSetJavaFilesOnly.calculateFileSet().toArray(new File[0]));

		jScrollPane.setViewportView(jList);
		jScrollPane.setPreferredSize(new Dimension(800, 600));
		
		JOptionPane.showMessageDialog(
				null,
				jScrollPane,
				"java source file set",
				JOptionPane.INFORMATION_MESSAGE);
  }
}